package com.lifeverse.service;

import com.lifeverse.entity.SystemAlert;
import com.lifeverse.entity.enums.AlertSeverity;
import com.lifeverse.entity.enums.AlertStatus;
import com.lifeverse.repository.SystemAlertRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 告警服务
 */
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional
public class AlertService {

    private final SystemAlertRepository alertRepository;
    private final NotificationService notificationService;

    /**
     * 创建告警
     */
    public SystemAlert createAlert(String alertName, String description, AlertSeverity severity, 
                                  String source, String ruleName, Map<String, String> labels, 
                                  Map<String, String> annotations, Double alertValue, Double threshold) {
        
        // 检查是否存在相同的活跃告警
        List<SystemAlert> existingAlerts = alertRepository.findDuplicateAlerts(ruleName, source);
        if (!existingAlerts.isEmpty()) {
            // 如果存在相同告警，增加告警次数
            SystemAlert existingAlert = existingAlerts.get(0);
            existingAlert.incrementAlertCount();
            log.info("增加重复告警次数: {} - {}", alertName, existingAlert.getAlertCount());
            return alertRepository.save(existingAlert);
        }

        SystemAlert alert = new SystemAlert();
        alert.setAlertName(alertName);
        alert.setDescription(description);
        alert.setSeverity(severity);
        alert.setStatus(AlertStatus.ACTIVE);
        alert.setSource(source);
        alert.setRuleName(ruleName);
        alert.setTriggeredAt(LocalDateTime.now());
        alert.setLastUpdatedAt(LocalDateTime.now());
        alert.setLabels(labels);
        alert.setAnnotations(annotations);
        alert.setAlertValue(alertValue);
        alert.setThreshold(threshold);

        SystemAlert savedAlert = alertRepository.save(alert);
        log.info("创建新告警: {} - 严重程度: {}", alertName, severity);

        // 发送通知
        sendAlertNotification(savedAlert);

        return savedAlert;
    }

    /**
     * 确认告警
     */
    public SystemAlert acknowledgeAlert(Long alertId, String acknowledgedBy) {
        Optional<SystemAlert> alertOpt = alertRepository.findById(alertId);
        if (alertOpt.isEmpty()) {
            throw new RuntimeException("告警不存在: " + alertId);
        }

        SystemAlert alert = alertOpt.get();
        if (alert.getStatus() != AlertStatus.ACTIVE) {
            throw new RuntimeException("只能确认活跃状态的告警");
        }

        alert.acknowledge(acknowledgedBy);
        SystemAlert savedAlert = alertRepository.save(alert);
        log.info("告警已确认: {} - 确认人: {}", alert.getAlertName(), acknowledgedBy);

        return savedAlert;
    }

    /**
     * 解决告警
     */
    public SystemAlert resolveAlert(Long alertId, String resolvedBy) {
        Optional<SystemAlert> alertOpt = alertRepository.findById(alertId);
        if (alertOpt.isEmpty()) {
            throw new RuntimeException("告警不存在: " + alertId);
        }

        SystemAlert alert = alertOpt.get();
        if (alert.getStatus() == AlertStatus.RESOLVED || alert.getStatus() == AlertStatus.CLOSED) {
            throw new RuntimeException("告警已经被解决");
        }

        alert.resolve(resolvedBy);
        SystemAlert savedAlert = alertRepository.save(alert);
        log.info("告警已解决: {} - 解决人: {} - 持续时间: {}秒", 
                alert.getAlertName(), resolvedBy, alert.getDurationInSeconds());

        return savedAlert;
    }

    /**
     * 获取活跃告警
     */
    @Transactional(readOnly = true)
    public List<SystemAlert> getActiveAlerts() {
        return alertRepository.findActiveAlerts();
    }

    /**
     * 获取高优先级活跃告警
     */
    @Transactional(readOnly = true)
    public List<SystemAlert> getHighPriorityActiveAlerts() {
        return alertRepository.findHighPriorityActiveAlerts();
    }

    /**
     * 根据条件查询告警
     */
    @Transactional(readOnly = true)
    public Page<SystemAlert> getAlertsByConditions(AlertStatus status, AlertSeverity severity, 
                                                  String source, LocalDateTime startTime, 
                                                  LocalDateTime endTime, Pageable pageable) {
        return alertRepository.findByConditions(status, severity, source, startTime, endTime, pageable);
    }

    /**
     * 获取告警统计信息
     */
    @Transactional(readOnly = true)
    public Map<String, Object> getAlertStatistics() {
        Map<String, Object> statistics = new java.util.HashMap<>();

        // 按状态统计
        List<Object[]> statusCounts = alertRepository.countByStatus();
        Map<String, Long> statusStats = statusCounts.stream()
                .collect(Collectors.toMap(
                        row -> ((AlertStatus) row[0]).name(),
                        row -> (Long) row[1]
                ));
        statistics.put("statusCounts", statusStats);

        // 按严重程度统计
        List<Object[]> severityCounts = alertRepository.countBySeverity();
        Map<String, Long> severityStats = severityCounts.stream()
                .collect(Collectors.toMap(
                        row -> ((AlertSeverity) row[0]).name(),
                        row -> (Long) row[1]
                ));
        statistics.put("severityCounts", severityStats);

        // 最近24小时按服务统计
        LocalDateTime since = LocalDateTime.now().minusHours(24);
        List<Object[]> sourceCounts = alertRepository.countBySourceSince(since);
        Map<String, Long> sourceStats = sourceCounts.stream()
                .collect(Collectors.toMap(
                        row -> (String) row[0],
                        row -> (Long) row[1]
                ));
        statistics.put("sourceCounts", sourceStats);

        // 告警趋势（最近24小时）
        List<Object[]> trendData = alertRepository.getAlertTrendLast24Hours(since);
        statistics.put("alertTrend", trendData);

        return statistics;
    }

    /**
     * 获取长时间未解决的告警
     */
    @Transactional(readOnly = true)
    public List<SystemAlert> getLongRunningAlerts(int hoursThreshold) {
        LocalDateTime threshold = LocalDateTime.now().minusHours(hoursThreshold);
        return alertRepository.findLongRunningAlerts(threshold);
    }

    /**
     * 发送告警通知
     */
    private void sendAlertNotification(SystemAlert alert) {
        try {
            // 根据严重程度决定通知方式
            if (alert.getSeverity().isUrgent()) {
                // 紧急告警：发送即时通知
                notificationService.sendUrgentNotification(alert);
            } else if (alert.getSeverity().isHighPriority()) {
                // 高优先级告警：发送普通通知
                notificationService.sendAlertNotification(alert);
            }

            // 标记通知已发送
            alert.setNotificationSent(true);
            alert.setNotificationSentAt(LocalDateTime.now());
            alertRepository.save(alert);

        } catch (Exception e) {
            log.error("发送告警通知失败: {}", alert.getAlertName(), e);
        }
    }

    /**
     * 批量处理告警
     */
    public void batchProcessAlerts(List<Long> alertIds, String action, String operator) {
        List<SystemAlert> alerts = alertRepository.findAllById(alertIds);
        
        for (SystemAlert alert : alerts) {
            switch (action.toLowerCase()) {
                case "acknowledge":
                    if (alert.getStatus() == AlertStatus.ACTIVE) {
                        alert.acknowledge(operator);
                    }
                    break;
                case "resolve":
                    if (alert.getStatus() != AlertStatus.RESOLVED && alert.getStatus() != AlertStatus.CLOSED) {
                        alert.resolve(operator);
                    }
                    break;
                case "suppress":
                    alert.setStatus(AlertStatus.SUPPRESSED);
                    alert.setLastUpdatedAt(LocalDateTime.now());
                    break;
            }
        }

        alertRepository.saveAll(alerts);
        log.info("批量处理告警完成: {} 个告警, 操作: {}, 操作人: {}", alerts.size(), action, operator);
    }

    /**
     * 清理过期的已解决告警
     */
    public void cleanupResolvedAlerts(int daysToKeep) {
        LocalDateTime threshold = LocalDateTime.now().minusDays(daysToKeep);
        alertRepository.deleteResolvedAlertsBefore(threshold);
        log.info("清理过期告警完成，保留天数: {}", daysToKeep);
    }

    /**
     * 重新发送未发送通知的告警
     */
    public void resendPendingNotifications() {
        List<SystemAlert> pendingAlerts = alertRepository.findAlertsNeedingNotification();
        
        for (SystemAlert alert : pendingAlerts) {
            sendAlertNotification(alert);
        }
        
        log.info("重新发送待发送通知的告警: {} 个", pendingAlerts.size());
    }
}